# RX-Base 项目管理 Makefile

# 默认目标
.DEFAULT_GOAL := help

# 颜色定义
RED := \033[31m
GREEN := \033[32m
YELLOW := \033[33m
BLUE := \033[34m
MAGENTA := \033[35m
CYAN := \033[36m
WHITE := \033[37m
RESET := \033[0m

# 项目信息
PROJECT_NAME := rx-base
VERSION := 1.0.0
DOCKER_COMPOSE := docker-compose
DOCKER := docker

# 环境变量
ENV_FILE := .env
ENV_EXAMPLE := .env.example

##@ 帮助信息

.PHONY: help
help: ## 显示帮助信息
	@echo "$(CYAN)RX-Base 在线教育平台 - 项目管理工具$(RESET)"
	@echo "$(YELLOW)版本: $(VERSION)$(RESET)"
	@echo ""
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ 环境设置

.PHONY: init
init: ## 初始化项目环境
	@echo "$(GREEN)正在初始化项目环境...$(RESET)"
	@if [ ! -f $(ENV_FILE) ]; then \
		cp $(ENV_EXAMPLE) $(ENV_FILE); \
		echo "$(YELLOW)已创建 .env 文件，请根据需要修改配置$(RESET)"; \
	else \
		echo "$(YELLOW).env 文件已存在$(RESET)"; \
	fi
	@echo "$(GREEN)项目环境初始化完成$(RESET)"

.PHONY: check-env
check-env: ## 检查环境配置
	@echo "$(GREEN)检查环境配置...$(RESET)"
	@if [ ! -f $(ENV_FILE) ]; then \
		echo "$(RED)错误: .env 文件不存在，请先运行 'make init'$(RESET)"; \
		exit 1; \
	fi
	@echo "$(GREEN)环境配置检查完成$(RESET)"

##@ 开发环境

.PHONY: dev
dev: check-env ## 启动开发环境
	@echo "$(GREEN)启动开发环境...$(RESET)"
	$(DOCKER_COMPOSE) up -d mysql redis
	@echo "$(YELLOW)等待数据库启动...$(RESET)"
	@sleep 10
	$(DOCKER_COMPOSE) up backend admin-web student-web mobile-web

.PHONY: dev-build
dev-build: check-env ## 构建并启动开发环境
	@echo "$(GREEN)构建并启动开发环境...$(RESET)"
	$(DOCKER_COMPOSE) up --build -d mysql redis
	@echo "$(YELLOW)等待数据库启动...$(RESET)"
	@sleep 10
	$(DOCKER_COMPOSE) up --build backend admin-web student-web mobile-web

.PHONY: dev-stop
dev-stop: ## 停止开发环境
	@echo "$(GREEN)停止开发环境...$(RESET)"
	$(DOCKER_COMPOSE) stop

.PHONY: dev-down
dev-down: ## 停止并删除开发环境容器
	@echo "$(GREEN)停止并删除开发环境容器...$(RESET)"
	$(DOCKER_COMPOSE) down

.PHONY: dev-logs
dev-logs: ## 查看开发环境日志
	$(DOCKER_COMPOSE) logs -f

##@ 生产环境

.PHONY: prod
prod: check-env ## 启动生产环境
	@echo "$(GREEN)启动生产环境...$(RESET)"
	$(DOCKER_COMPOSE) -f docker-compose.yml -f docker-compose.prod.yml up -d

.PHONY: prod-build
prod-build: check-env ## 构建并启动生产环境
	@echo "$(GREEN)构建并启动生产环境...$(RESET)"
	$(DOCKER_COMPOSE) -f docker-compose.yml -f docker-compose.prod.yml up --build -d

.PHONY: prod-stop
prod-stop: ## 停止生产环境
	@echo "$(GREEN)停止生产环境...$(RESET)"
	$(DOCKER_COMPOSE) -f docker-compose.yml -f docker-compose.prod.yml stop

.PHONY: prod-down
prod-down: ## 停止并删除生产环境容器
	@echo "$(GREEN)停止并删除生产环境容器...$(RESET)"
	$(DOCKER_COMPOSE) -f docker-compose.yml -f docker-compose.prod.yml down

##@ 数据库管理

.PHONY: db-migrate
db-migrate: ## 运行数据库迁移
	@echo "$(GREEN)运行数据库迁移...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run migrate

.PHONY: db-seed
db-seed: ## 运行数据库种子
	@echo "$(GREEN)运行数据库种子...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run seed

.PHONY: db-reset
db-reset: ## 重置数据库
	@echo "$(RED)警告: 这将删除所有数据库数据!$(RESET)"
	@read -p "确定要继续吗? [y/N] " confirm && [ "$$confirm" = "y" ] || exit 1
	@echo "$(GREEN)重置数据库...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run db:reset

.PHONY: db-backup
db-backup: ## 备份数据库
	@echo "$(GREEN)备份数据库...$(RESET)"
	@mkdir -p backups
	$(DOCKER_COMPOSE) exec mysql mysqldump -u root -p$$(grep MYSQL_ROOT_PASSWORD .env | cut -d '=' -f2) rxbase > backups/backup_$$(date +%Y%m%d_%H%M%S).sql
	@echo "$(GREEN)数据库备份完成$(RESET)"

.PHONY: db-restore
db-restore: ## 恢复数据库 (使用: make db-restore FILE=backup.sql)
	@if [ -z "$(FILE)" ]; then \
		echo "$(RED)错误: 请指定备份文件，例如: make db-restore FILE=backup.sql$(RESET)"; \
		exit 1; \
	fi
	@echo "$(GREEN)恢复数据库...$(RESET)"
	$(DOCKER_COMPOSE) exec -T mysql mysql -u root -p$$(grep MYSQL_ROOT_PASSWORD .env | cut -d '=' -f2) rxbase < $(FILE)
	@echo "$(GREEN)数据库恢复完成$(RESET)"

##@ 测试

.PHONY: test
test: ## 运行所有测试
	@echo "$(GREEN)运行所有测试...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm test

.PHONY: test-unit
test-unit: ## 运行单元测试
	@echo "$(GREEN)运行单元测试...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run test:unit

.PHONY: test-integration
test-integration: ## 运行集成测试
	@echo "$(GREEN)运行集成测试...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run test:integration

.PHONY: test-e2e
test-e2e: ## 运行端到端测试
	@echo "$(GREEN)运行端到端测试...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run test:e2e

.PHONY: test-coverage
test-coverage: ## 生成测试覆盖率报告
	@echo "$(GREEN)生成测试覆盖率报告...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run test:coverage

##@ 代码质量

.PHONY: lint
lint: ## 运行代码检查
	@echo "$(GREEN)运行代码检查...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run lint
	$(DOCKER_COMPOSE) exec admin-web npm run lint
	$(DOCKER_COMPOSE) exec student-web npm run lint
	$(DOCKER_COMPOSE) exec mobile-web npm run lint

.PHONY: lint-fix
lint-fix: ## 自动修复代码问题
	@echo "$(GREEN)自动修复代码问题...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run lint:fix
	$(DOCKER_COMPOSE) exec admin-web npm run lint:fix
	$(DOCKER_COMPOSE) exec student-web npm run lint:fix
	$(DOCKER_COMPOSE) exec mobile-web npm run lint:fix

.PHONY: format
format: ## 格式化代码
	@echo "$(GREEN)格式化代码...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run format
	$(DOCKER_COMPOSE) exec admin-web npm run format
	$(DOCKER_COMPOSE) exec student-web npm run format
	$(DOCKER_COMPOSE) exec mobile-web npm run format

##@ 构建和部署

.PHONY: build
build: ## 构建所有镜像
	@echo "$(GREEN)构建所有镜像...$(RESET)"
	$(DOCKER_COMPOSE) build

.PHONY: build-backend
build-backend: ## 构建后端镜像
	@echo "$(GREEN)构建后端镜像...$(RESET)"
	$(DOCKER_COMPOSE) build backend

.PHONY: build-frontend
build-frontend: ## 构建前端镜像
	@echo "$(GREEN)构建前端镜像...$(RESET)"
	$(DOCKER_COMPOSE) build admin-web student-web mobile-web

.PHONY: push
push: ## 推送镜像到仓库
	@echo "$(GREEN)推送镜像到仓库...$(RESET)"
	$(DOCKER_COMPOSE) push

.PHONY: deploy
deploy: ## 部署到生产环境
	@echo "$(GREEN)部署到生产环境...$(RESET)"
	@echo "$(YELLOW)请确保已经构建并推送了最新镜像$(RESET)"
	$(MAKE) prod-down
	$(MAKE) prod-build
	@echo "$(GREEN)部署完成$(RESET)"

##@ 监控和日志

.PHONY: logs
logs: ## 查看所有服务日志
	$(DOCKER_COMPOSE) logs -f

.PHONY: logs-backend
logs-backend: ## 查看后端日志
	$(DOCKER_COMPOSE) logs -f backend

.PHONY: logs-frontend
logs-frontend: ## 查看前端日志
	$(DOCKER_COMPOSE) logs -f admin-web student-web mobile-web

.PHONY: logs-db
logs-db: ## 查看数据库日志
	$(DOCKER_COMPOSE) logs -f mysql redis

.PHONY: status
status: ## 查看服务状态
	@echo "$(GREEN)服务状态:$(RESET)"
	$(DOCKER_COMPOSE) ps

.PHONY: stats
stats: ## 查看资源使用情况
	@echo "$(GREEN)资源使用情况:$(RESET)"
	$(DOCKER) stats $$($(DOCKER_COMPOSE) ps -q)

##@ 维护

.PHONY: clean
clean: ## 清理未使用的 Docker 资源
	@echo "$(GREEN)清理未使用的 Docker 资源...$(RESET)"
	$(DOCKER) system prune -f
	$(DOCKER) volume prune -f
	$(DOCKER) network prune -f

.PHONY: clean-all
clean-all: ## 清理所有 Docker 资源 (危险操作)
	@echo "$(RED)警告: 这将删除所有 Docker 镜像、容器、卷和网络!$(RESET)"
	@read -p "确定要继续吗? [y/N] " confirm && [ "$$confirm" = "y" ] || exit 1
	@echo "$(GREEN)清理所有 Docker 资源...$(RESET)"
	$(DOCKER_COMPOSE) down -v --rmi all
	$(DOCKER) system prune -a -f --volumes

.PHONY: update
update: ## 更新项目依赖
	@echo "$(GREEN)更新项目依赖...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm update
	$(DOCKER_COMPOSE) exec admin-web npm update
	$(DOCKER_COMPOSE) exec student-web npm update
	$(DOCKER_COMPOSE) exec mobile-web npm update

.PHONY: security-check
security-check: ## 安全检查
	@echo "$(GREEN)运行安全检查...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm audit
	$(DOCKER_COMPOSE) exec admin-web npm audit
	$(DOCKER_COMPOSE) exec student-web npm audit
	$(DOCKER_COMPOSE) exec mobile-web npm audit

##@ 工具

.PHONY: shell-backend
shell-backend: ## 进入后端容器 shell
	$(DOCKER_COMPOSE) exec backend /bin/bash

.PHONY: shell-mysql
shell-mysql: ## 进入 MySQL 容器
	$(DOCKER_COMPOSE) exec mysql mysql -u root -p

.PHONY: shell-redis
shell-redis: ## 进入 Redis 容器
	$(DOCKER_COMPOSE) exec redis redis-cli

.PHONY: install-backend
install-backend: ## 安装后端依赖
	$(DOCKER_COMPOSE) exec backend npm install

.PHONY: install-frontend
install-frontend: ## 安装前端依赖
	$(DOCKER_COMPOSE) exec admin-web npm install
	$(DOCKER_COMPOSE) exec student-web npm install
	$(DOCKER_COMPOSE) exec mobile-web npm install

.PHONY: docs
docs: ## 生成 API 文档
	@echo "$(GREEN)生成 API 文档...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run docs:generate

.PHONY: docs-serve
docs-serve: ## 启动文档服务器
	@echo "$(GREEN)启动文档服务器...$(RESET)"
	$(DOCKER_COMPOSE) exec backend npm run docs:serve

##@ 快速命令

.PHONY: quick-start
quick-start: init dev ## 快速启动项目 (初始化 + 开发环境)

.PHONY: quick-reset
quick-reset: dev-down clean dev ## 快速重置项目 (停止 + 清理 + 启动)

.PHONY: quick-test
quick-test: lint test ## 快速测试 (代码检查 + 测试)

# 检查必要的工具
.PHONY: check-tools
check-tools: ## 检查必要的工具
	@echo "$(GREEN)检查必要的工具...$(RESET)"
	@command -v docker >/dev/null 2>&1 || { echo "$(RED)错误: Docker 未安装$(RESET)"; exit 1; }
	@command -v docker-compose >/dev/null 2>&1 || { echo "$(RED)错误: Docker Compose 未安装$(RESET)"; exit 1; }
	@echo "$(GREEN)所有必要工具已安装$(RESET)"

# 显示项目信息
.PHONY: info
info: ## 显示项目信息
	@echo "$(CYAN)项目名称:$(RESET) $(PROJECT_NAME)"
	@echo "$(CYAN)版本:$(RESET) $(VERSION)"
	@echo "$(CYAN)Docker Compose 文件:$(RESET) docker-compose.yml"
	@echo "$(CYAN)环境文件:$(RESET) $(ENV_FILE)"
	@echo "$(CYAN)服务列表:$(RESET)"
	@echo "  - backend (Node.js API)"
	@echo "  - admin-web (管理后台)"
	@echo "  - student-web (PC学生端)"
	@echo "  - mobile-web (移动Web端)"
	@echo "  - mysql (数据库)"
	@echo "  - redis (缓存)"
	@echo "  - nginx (反向代理)"

# 确保在执行某些命令前检查工具
init: check-tools
dev: check-tools
prod: check-tools